home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Comm / AmiTCP30b2.lha / src / util / finger / lprint.c < prev    next >
C/C++ Source or Header  |  1994-02-24  |  10KB  |  350 lines

  1. RCS_ID_C = "$Id: lprint.c,v 6.4 1994/02/21 19:30:06 ppessi Exp $";
  2.  
  3. /*
  4.  * lprint.c - print finger information in long format
  5.  *
  6.  * Copyright © 1993 AmiTCP/IP Group, <AmiTCP-group@hut.fi>
  7.  *                  Helsinki University of Technology, Finland.
  8.  *
  9.  * This program is derived from original work distributed in BSD Net 2.
  10.  *
  11.  * Created      : Fri Oct 15 01:29:07 1993 ppessi
  12.  * Last modified: Mon Feb 21 03:15:25 1994 ppessi
  13.  *
  14.  * $Log: lprint.c,v $
  15.  * Revision 6.4  1994/02/21  19:30:06  ppessi
  16.  * Removed tty field. Real release 2.
  17.  *
  18.  * Revision 6.3  1994/02/15  14:56:43  ppessi
  19.  * Added utmp support
  20.  *
  21.  * Revision 6.2  93/10/15  03:00:11  ppessi
  22.  * Polished AmiTCP support
  23.  * 
  24.  */
  25.  
  26. /* Copyright (c) 1989 The Regents of the University of California.
  27.  * All rights reserved.
  28.  *
  29.  * This code is derived from software contributed to Berkeley by
  30.  * Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
  31.  *
  32.  * Redistribution and use in source and binary forms, with or without
  33.  * modification, are permitted provided that the following conditions
  34.  * are met:
  35.  * 1. Redistributions of source code must retain the above copyright
  36.  *    notice, this list of conditions and the following disclaimer.
  37.  * 2. Redistributions in binary form must reproduce the above copyright
  38.  *    notice, this list of conditions and the following disclaimer in the
  39.  *    documentation and/or other materials provided with the distribution.
  40.  * 3. All advertising materials mentioning features or use of this software
  41.  *    must display the following acknowledgement:
  42.  *    This product includes software developed by the University of
  43.  *    California, Berkeley and its contributors.
  44.  * 4. Neither the name of the University nor the names of its contributors
  45.  *    may be used to endorse or promote products derived from this software
  46.  *    without specific prior written permission.
  47.  *
  48.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  49.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  50.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  51.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  52.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  53.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  54.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  55.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  56.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  57.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  58.  * SUCH DAMAGE.
  59.  */
  60.  
  61. #include <sys/types.h>
  62. #include <sys/time.h>
  63. #include <tzfile.h>
  64. #include <string.h>
  65. #include <stdlib.h>
  66. #include <stdio.h>
  67. #include <ctype.h>
  68. #if !AMIGA
  69. #include <paths.h>
  70. #endif
  71. #include "finger.h"
  72.  
  73. #define    LINE_LEN    80
  74. #define    TAB_LEN        8        /* 8 spaces between tabs */
  75. #define    _PATH_PLAN    ".plan"
  76. #define    _PATH_PROJECT    ".project"
  77. #if AMIGA
  78. #define _PATH_BSHELL "CLI"
  79. #endif
  80.  
  81. void lprint(register PERSON *pn);
  82. int show_text(char *directory, char *file_name, char *header);
  83. int demi_print(char *str, int oddfield);
  84. void vputc(register int ch);
  85.  
  86. void
  87. lflag_print(void)
  88. {
  89.   extern int pplan;
  90.   register PERSON *pn;
  91.  
  92.   for (pn = phead;;) {
  93.     lprint(pn);
  94.     if (!pplan) {
  95.       (void)show_text(pn->dir, _PATH_PROJECT, "Project:");
  96.       if (!show_text(pn->dir, _PATH_PLAN, "Plan:"))
  97.     (void)printf("No Plan.\n");
  98.     }
  99.     if (!(pn = pn->next))
  100.       break;
  101.     putchar('\n');
  102.   }
  103. }
  104.  
  105. void
  106. lprint(register PERSON *pn)
  107. {
  108.   extern time_t now;
  109.   register struct tm *delta;
  110.   register WHERE *w;
  111.   register int cpr, len, maxlen;
  112.   struct tm *tp;
  113.   int oddfield;
  114.   time_t time();
  115.   char *t, *tzn, *prphone();
  116.  
  117.   /*
  118.    * long format --
  119.    *    login name
  120.    *    real name
  121.    *    home directory
  122.    *    shell
  123.    *    office, office phone, home phone if available
  124.    */
  125.   (void)printf("Login: %-15s\t\t\tName: %s\nDirectory: %-25s",
  126.            pn->name, pn->realname, pn->dir);
  127.   (void)printf("\tShell: %-s\n", *pn->shell ? pn->shell : _PATH_BSHELL);
  128.  
  129.   /*
  130.    * try and print office, office phone, and home phone on one line;
  131.    * if that fails, do line filling so it looks nice.
  132.    */
  133. #define    OFFICE_TAG        "Office"
  134. #define    OFFICE_PHONE_TAG    "Office Phone"
  135.   oddfield = 0;
  136.   if (pn->office && pn->officephone &&
  137.       strlen(pn->office) + strlen(pn->officephone) +
  138.       sizeof(OFFICE_TAG) + 2 <= 5 * TAB_LEN) {
  139.     (void)sprintf(tbuf, "%s: %s, %s", OFFICE_TAG, pn->office,
  140.           prphone(pn->officephone));
  141.     oddfield = demi_print(tbuf, oddfield);
  142.   } else {
  143.     if (pn->office) {
  144.       (void)sprintf(tbuf, "%s: %s", OFFICE_TAG, pn->office);
  145.       oddfield = demi_print(tbuf, oddfield);
  146.     }
  147.     if (pn->officephone) {
  148.       (void)sprintf(tbuf, "%s: %s", OFFICE_PHONE_TAG,
  149.             prphone(pn->officephone));
  150.       oddfield = demi_print(tbuf, oddfield);
  151.     }
  152.   }
  153.   if (pn->homephone) {
  154.     (void)sprintf(tbuf, "%s: %s", "Home Phone",
  155.           prphone(pn->homephone));
  156.     oddfield = demi_print(tbuf, oddfield);
  157.   }
  158.   if (oddfield)
  159.     putchar('\n');
  160.  
  161.   /*
  162.    * long format con't: * if logged in
  163.    *    terminal
  164.    *    idle time
  165.    *    if messages allowed
  166.    *    where logged in from
  167.    * if not logged in
  168.    *    when last logged in
  169.    */
  170. #ifdef HAVE_TTY
  171.   /* find out longest device name for this user for formatting */
  172.   for (w = pn->whead, maxlen = -1; w != NULL; w = w->next)
  173.     if ((len = strlen(w->tty)) > maxlen)
  174.       maxlen = len;
  175. #endif
  176.   /* find rest of entries for user */
  177.   for (w = pn->whead; w != NULL; w = w->next) {
  178.     switch (w->info) {
  179.     case LOGGEDIN:
  180.       tp = localtime(&w->loginat);
  181.       t = asctime(tp);
  182. #if HAVE_TZONE
  183.       tzn = tp->tm_zone;
  184. #else
  185.       tzn = getenv("TZ"); 
  186.       if (!tzn) tzn = "Local";
  187. #endif
  188. #ifdef HAVE_TTY
  189.       cpr = printf("On since %.16s (%s) on %s",
  190.            t, tzn, w->tty);
  191.       /*
  192.        * idle time is tough; if have one, print a comma,
  193.        * then spaces to pad out the device name, then the
  194.        * idle time.  Follow with a comma if a remote login.
  195.        */
  196.       delta = gmtime(&w->idletime);
  197.       if (delta->tm_yday || delta->tm_hour || delta->tm_min) {
  198.     cpr += printf("%-*s idle ",
  199.               maxlen - strlen(w->tty) + 1, ",");
  200.     if (delta->tm_yday > 0) {
  201.       cpr += printf("%d day%s ",
  202.             delta->tm_yday,
  203.             delta->tm_yday == 1 ? "" : "s");
  204.     }
  205.     cpr += printf("%d:%02d",
  206.               delta->tm_hour, delta->tm_min);
  207.     if (*w->host) {
  208.       putchar(',');
  209.       ++cpr;
  210.     }
  211.       }
  212.       if (!w->writable)
  213.     cpr += printf(" (messages off)");
  214. #else
  215.       cpr = printf("On since %.16s (%s)", 
  216.              t, tzn);
  217. #endif
  218.       break;
  219.     case LASTLOG:
  220.       if (w->loginat == 0) {
  221.     (void)printf("Never logged in.");
  222.     break;
  223.       }
  224.       tp = localtime(&w->loginat);
  225.       t = asctime(tp);
  226. #if HAVE_TZONE
  227.       tzn = tp->tm_zone;
  228. #else
  229.       tzn = getenv("TZ");
  230.       if (!tzn) tzn = "Local";
  231. #endif
  232. #ifdef HAVE_TTY
  233.       if (now - w->loginat > SECSPERDAY * DAYSPERNYEAR / 2)
  234.     cpr = printf("Last login %.16s %.4s (%s) on %s",
  235.              t, t + 20, tzn, w->tty);
  236.       else
  237.     cpr = printf("Last login %.16s (%s) on %s",
  238.              t, tzn, w->tty);
  239. #else
  240.       if (now - w->loginat > SECSPERDAY * DAYSPERNYEAR / 2)
  241.     cpr = printf("Last login %.16s %.4s (%s)",
  242.              t, t + 20, tzn);
  243.       else
  244.     cpr = printf("Last login %.16s (%s)",
  245.              t, tzn);
  246. #endif
  247.       break;
  248.     }
  249.     if (*w->host) {
  250.       if (LINE_LEN < (cpr + 6 + strlen(w->host)))
  251.     (void)printf("\n   ");
  252.       (void)printf(" from %s", w->host);
  253.     }
  254.     putchar('\n');
  255.   }
  256. }
  257.  
  258. int
  259. demi_print(char *str, int oddfield)
  260. {
  261.   static int lenlast;
  262.   int lenthis, maxlen;
  263.  
  264.   lenthis = strlen(str);
  265.   if (oddfield) {
  266.     /*
  267.      * We left off on an odd number of fields.  If we haven't
  268.      * crossed the midpoint of the screen, and we have room for
  269.      * the next field, print it on the same line; otherwise,
  270.      * print it on a new line.
  271.      *
  272.      * Note: we insist on having the right hand fields start
  273.      * no less than 5 tabs out.
  274.      */
  275.     maxlen = 5 * TAB_LEN;
  276.     if (maxlen < lenlast)
  277.       maxlen = lenlast;
  278.     if (((((maxlen / TAB_LEN) + 1) * TAB_LEN) +
  279.      lenthis) <= LINE_LEN) {
  280.       while(lenlast < (4 * TAB_LEN)) {
  281.     putchar('\t');
  282.     lenlast += TAB_LEN;
  283.       }
  284.       (void)printf("\t%s\n", str); /* force one tab */
  285.     } else {
  286.       (void)printf("\n%s", str); /* go to next line */
  287.       oddfield = !oddfield;    /* this'll be undone below */
  288.     }
  289.   } else
  290.     (void)printf("%s", str);
  291.   oddfield = !oddfield;        /* toggle odd/even marker */
  292.   lenlast = lenthis;
  293.   return(oddfield);
  294. }
  295.  
  296. int
  297. show_text(char *directory, char *file_name, char *header)
  298. {
  299.   register int ch, lastc;
  300.   register FILE *fp;
  301.  
  302. #if AMIGA
  303.   {
  304.     char *dp = tbuf;
  305.     while (*dp = *directory++)
  306.       dp++;
  307.     if (dp[-1] != '/' && dp[-1] != ':')  
  308.       *dp++ = '/';
  309.     while (*dp++ = *file_name++)
  310.       ;
  311.   }
  312. #else
  313.   (void)sprintf(tbuf, "%s/%s", directory, file_name);
  314. #endif
  315.   if ((fp = fopen(tbuf, "r")) == NULL)
  316.     return(0);
  317.   (void)printf("%s\n", header);
  318.   while ((ch = getc(fp)) != EOF)
  319.     vputc(lastc = ch);
  320.   if (lastc != '\n')
  321.     (void)putchar('\n');
  322.   (void)fclose(fp);
  323.   return(1);
  324. }
  325.  
  326. void
  327. vputc(register int ch)
  328. {
  329. #if !AMIGA
  330.   int meta;
  331.  
  332.   if (!isascii(ch)) {
  333.     (void)putchar('M');
  334.     (void)putchar('-');
  335.     ch = toascii(ch);
  336.     meta = 1;
  337.   } else
  338.     meta = 0;
  339.   if (isprint(ch) || !meta && (ch == ' ' || ch == '\t' || ch == '\n'))
  340.     (void)putchar(ch);
  341. #else /* AMIGA */
  342.   if (isprint(ch) || (ch == ' ' || ch == '\t' || ch == '\n'))
  343.     (void)putchar(ch);
  344. #endif
  345.   else {
  346.     (void)putchar('^');
  347.     (void)putchar(ch == '\177' ? '?' : ch | 0100);
  348.   }
  349. }
  350.